#include "normalenemy.h"
#include "../effect.h"
#include "path.h"
namespace fireplane{


	NormalEnemy::NormalEnemy(EnemyType type):
		Enemy(type){

	}

	bool NormalEnemy::updateState( float dt ){
		bool ret = true;

		if (isDestroy())
		{
			return false;
		}

		if (_is_attak)
		{
			_attack_back_time += dt;
			if (_attack_back_time > 0.5f)
			{
				_attack_back_time = 0;
				_is_attak = false;
				_sprite->setColor(ccc3(255,255,255));
			}
		}
		goBeizer(dt);

		CCPoint pos = this->getPosition();
		if (pos.y < -50)
		{
			ret =  false;
		}

		list<CCRect>::iterator it = _all_collision_rects.begin();
		for (;it != _all_collision_rects.end();it ++)
		{
			CCRect& rect = (*it);
			rect.origin.x = pos.x - rect.size.width / 2;
			rect.origin.y = pos.y - rect.size.height / 2;
		}

		return ret;
	}

	NormalEnemy::~NormalEnemy(){}

	void NormalEnemy::calcNextPos(){
		Bezier *bezier = *_bezier_it;
		_next_pos = Path::getPath()->hornbez2(bezier->point,(float) _cur_step / (float)_total_step);
	}
	void NormalEnemy::onInit(CreateArg* arg)
	{
		CreateNormalEnemy* targ = (CreateNormalEnemy*)arg;

		_sprite = CCSprite::create("enemy/enemy0.png");
		addChild(_sprite);
		_sprite->setRotation(180);
		this->setPosition(targ->pos);

		CCSize contentsize = _sprite->getContentSize();
		CCRect rect = CCRectMake(targ->pos.x - contentsize.width / 2,targ->pos.y - contentsize.height / 2,contentsize.width,
			contentsize.height);

		_all_collision_rects.push_back(rect);

		_hp = 100;
		_is_attak = false;
		_attack_back_time = 0;

		BezierList* data = Path::getPath()->getBezierList("enemy");

		_bezier_list = new BezierList();

		list<Bezier*>::iterator it = data->begin();

		int idx = 0;
		CCPoint start_pos;
		for (;it != data->end();it ++)
		{
			Bezier* b = (*it);
			Bezier* n = new Bezier();
			for(int i = 0;i < e_bezier_point_max;i++){
				n->point[i] = b->point[i];

				if(idx == 0){
					start_pos = n->point[i];
				}

				n->point[i].x -= start_pos.x;
				n->point[i].y -= start_pos.y;

				n->point[i].x += targ->pos.x;
				n->point[i].y += targ->pos.y;

				idx ++;
			}

			_bezier_list->push_back(n);
		}

		_bezier_it = _bezier_list->begin();

		_total_step = 1000;
		_cur_step = 1;
		_speed = 200.0f;
		calcNextPos();
	}

	void NormalEnemy::destroy()
	{
		Enemy::destroy();

		list<Bezier*>::iterator it = _bezier_list->begin();
		for (;it != _bezier_list->end();it ++)
		{
			Bezier* b = (*it);
			delete b;
		}

		delete _bezier_list;
		_bezier_list = NULL;
	}

	void NormalEnemy::onCollision2Player(){
		_onAttack(-_hp);
	}

	void NormalEnemy::_onAttack(int addHp){
		_hp += addHp;
		if (_hp <= 0)
		{
			_hp = 0;
			setDestroyFlag(true);

			// create effect
			CCPoint worldpos = this->getPosition();
			worldpos = this->getParent()->convertToWorldSpace(worldpos);

			Effect::CreateBomb0OrBomb1 cmd;
			cmd._id = Effect::ET_bomb0;
			cmd.worldPos = worldpos;

			Effect::createEffect(&cmd);
		}

		_sprite->setColor(ccc3(180,0,0));
		_is_attak = true;
		_attack_back_time = 0;
	}

	void NormalEnemy::onAttack()
	{
		_onAttack(-10);
	}

	void NormalEnemy::goBeizer(float dt)	
	{
		if( _bezier_it == _bezier_list->end())
			return;

		CCPoint lastPos = this->getPosition();

		Bezier *bezier = NULL;
		bool change = false;
		float move = _speed * dt;
	
		while(1){
			CCPoint pos = this->getPosition();
			CCPoint dir = ccpSub(_next_pos,pos);
			float dis = ccpLength(dir);

			change = false;
			float tmove = move;
			if(move > dis){
				move -= dis;
				tmove = dis;
				change = true;
			}

			dir = ccpNormalize(dir);

			CCPoint v_move = dir;
			v_move.x *= tmove;
			v_move.y *= tmove;

			pos.x += v_move.x;
			pos.y += v_move.y;

			this->setPosition(pos);
			if(change){
				_cur_step ++;
				if(_cur_step > _total_step){
					_bezier_it++;
					_cur_step = 1;
				}

				if( _bezier_it != _bezier_list->end()){
					calcNextPos();
				}
				else{
					break;
				}
			}
			else{
				break;
			}
		}

		calcRoate(lastPos);
		
		
#if 0
		CCPoint pos = CCPointZero;
		do{
			if( _bezier_it == _bezier_list->end())
				break;

			bezier = (Bezier*)*_bezier_it;

			bool change = false;
			float add = 0;
			time_lost += dt;
			if(time_lost > time_total){
				change = true;
				add = time_lost - time_total;
				time_lost = time_total;
			}
			
			tt = time_lost / time_total;
			pos  = Path::getPath()->hornbez2(bezier->point,tt);
			setRotate(pos,tt);
			
			if(change){
				_bezier_it++;
				time_lost = add;
			}
		}while(0);
#endif
	}


	void NormalEnemy::calcRoate(CCPoint lastPos)
	{
		CCPoint curpos = this->getPosition();
		CCPoint vector = ccpSub(curpos,lastPos);
		if(vector.equals(CCPointZero)){
			vector.setPoint(0,-1);
		}

		vector = ccpNormalize(vector);
		float degree = CC_RADIANS_TO_DEGREES(acos(ccpDot(vector,ccp(0,1))));

		if (ccpCross(vector,ccp(0,1)) < 0)
		{
			degree = 360 - degree;
		}

		degree += 180;
		this->setRotation(degree);
	}
}